
/* --------------------------------------- Include Files ---------------------------------------- */
#include "stm32f10x.h"
#include "system_timer.h"
#include "driver.h"
#include "crc16.h"
#include "parameter.h"

/* ---------------------------------------- Macro Defines --------------------------------------- */

/* -------------------------------------- Data Type Defines -------------------------------------- */
typedef struct
{
    uint32_t    pk;
    uint32_t    offset;
    uint8_t     permission;
    uint8_t     lock;
    uint16_t    length;
    uint8_t    *pdata;
} DBS_TABLE_ITEM;


/* --------------------------------- Global Function Prototypes --------------------------------- */
uint32_t Dbs_initParTable(void);
uint32_t Dbs_setParDefault(void);
uint32_t Dbs_getParLength(uint32_t pk, uint32_t *length);
uint32_t Dbs_setParValue(uint32_t pk, uint8_t *data, uint32_t length);
uint32_t Dbs_getParValue(uint32_t pk, uint8_t *data, uint32_t *length);
uint32_t Dbs_getParLength(uint32_t pk, uint32_t *length);

/* -------------------------------------- Static Variables -------------------------------------- */
const uint32_t dbs_par_rows = dbs_par_pk_number;
const uint32_t dbs_par_memstart = 10;
const uint32_t dbs_par_memsize = 290;
const uint32_t dbs_par_amemstart = dbs_par_memstart;
const uint32_t dbs_par_bmemstart = dbs_par_amemstart + dbs_par_memsize;
volatile uint8_t dbs_par_memory[dbs_par_memsize];

const uint8_t dbs_parinit_crc[2]                            = {0X00, 0X00};
const uint8_t dbs_parinit_isinit[1]                         = {0X00};
const uint8_t dbs_parinit_locksn[6]                         = {0x03,0x10,0x00,0x18,0x00,0x08};				//LOCK SN
const uint8_t dbs_parinit_appkeysn[6]                       = {0x00};				//APP&KEY SN
const uint8_t dbs_parinit_stype[1]                          = {0x00};				//终端类型
const uint8_t dbs_parinit_randnumtimes[1]                   = {60};
const uint8_t dbs_parinit_onlockopprostate[7]               = {0x00};				//开锁过程时间+状态
const uint8_t dbs_parinit_offlockopprostate[7]              = {0x00};				//关锁过程时间+状态
const uint8_t dbs_parinit_mototimeout[1]                    = {10};
const uint8_t dbs_parinit_userid[2] 						= {0x00,0x00};
const uint8_t dbs_parinit_currentseq[1]						= {0};					//存储记录序号
const uint8_t dbs_parinit_totalmun[1]						= {10};					//存储记录总数
const uint8_t dbs_parinit_storage0[22]						= {0x00};				//存储扇区							
const uint8_t dbs_parinit_storage1[22]						= {0x00};					
const uint8_t dbs_parinit_storage2[22]						= {0x00};
const uint8_t dbs_parinit_storage3[22]						= {0x00};
const uint8_t dbs_parinit_storage4[22]						= {0x00};
const uint8_t dbs_parinit_storage5[22]						= {0x00};
const uint8_t dbs_parinit_storage6[22]						= {0x00};
const uint8_t dbs_parinit_storage7[22]						= {0x00};
const uint8_t dbs_parinit_storage8[22]						= {0x00};
const uint8_t dbs_parinit_storage9[22]						= {0x00};
const uint8_t dbs_parinit_storage10[22]						= {0x00};
const uint8_t dbs_parinit_encryptionkey[16]					= {0x63, 0x80, 0xAF, 0xE6, 0x60, 0xBF, 0x56, 0x1E, 0x7F, 0x67, 0x7D, 0xC7, 0xFA, 0xAB, 0xA9, 0xCD};
const uint8_t dbs_parinit_onlockresult[1]					= {0x00};
const uint8_t dbs_parinit_offlockresult[1]					= {0x00};
const uint8_t dbs_parinit_Roderrmotor[1]					= {0x00};
const uint8_t dbs_parinit_bolnofind[1]						= {0x00};
const uint8_t dbs_parinit_bolerropen[1]						= {0x00};
const uint8_t dbs_parinit_reportfaulttimes[1]				= {60};
const uint8_t dbs_parinit_firmwarerev[4]					= {0};
const uint8_t dbs_parinit_seqnumfull[1]						= {0};

volatile DBS_TABLE_ITEM dbs_par_format[] =
{
    {dbs_par_pk_crc,                            0,        0x10,     0,     2, (uint8_t *)dbs_parinit_crc},
    {dbs_par_pk_isinit,                         2,        0x10,     0,     1, (uint8_t *)dbs_parinit_isinit},
    {dbs_par_pk_locksn,                         3,        0x10,     0,     6, (uint8_t *)dbs_parinit_locksn},
	{dbs_par_pk_appkeysn,                       9,        0x10,     0,     6, (uint8_t *)dbs_parinit_locksn},
    {dbs_par_pk_stype,                         	15,       0x10,     0,     1, (uint8_t *)dbs_parinit_stype},
    {dbs_par_pk_randnumtimes, 					16,       0x10,     0,     1, (uint8_t *)dbs_parinit_randnumtimes},
    {dbs_par_pk_onlockopprostate,				17,       0x10,     0,     7, (uint8_t *)dbs_parinit_onlockopprostate},
    {dbs_par_pk_offlockopprostate,				24,		  0x10,     0,     7, (uint8_t *)dbs_parinit_offlockopprostate},
	{dbs_par_pk_mototimeout,					31,		  0x10,     0,     1, (uint8_t *)dbs_parinit_mototimeout},
	{dbs_par_pk_userid,							32,		  0x10,     0,     2, (uint8_t *)dbs_parinit_userid},
	{dbs_par_pk_currentseq,						34,		  0x10,     0,     1, (uint8_t *)dbs_parinit_currentseq},
	{dbs_par_pk_totalmun,						35,		  0x10,     0,     1, (uint8_t *)dbs_parinit_totalmun},
	{dbs_par_pk_encryptionkey,					36,	  	  0x10,     0,     16, (uint8_t *)dbs_parinit_encryptionkey},
	{dbs_par_pk_onlockresult,					52,	      0x10,     0,     1,  (uint8_t *)dbs_parinit_onlockresult},
	{dbs_par_pk_offlockresult,					53,	      0x10,     0,     1,  (uint8_t *)dbs_parinit_offlockresult},
	{dbs_par_pk_Roderrmotor,					54,	      0x10,     0,     1,  (uint8_t *)dbs_parinit_Roderrmotor},	
	{dbs_par_pk_bolnofind,						55,	      0x10,     0,     1,  (uint8_t *)dbs_parinit_bolnofind},	
	{dbs_par_pk_bolerropen,						56,	      0x10,     0,     1,  (uint8_t *)dbs_parinit_bolerropen},
	{dbs_par_pk_reportfaulttimes,				57,	      0x10,     0,     1,  (uint8_t *)dbs_parinit_reportfaulttimes},
	{dbs_par_pk_firmwarerev,					58,		  0x10,		0,	   1,  (uint8_t *)dbs_parinit_firmwarerev},
	{dbs_par_pk_storage0,						59,		  0x10,     0,     22, (uint8_t *)dbs_parinit_storage0},
	{dbs_par_pk_storage1,						81,		  0x10,     0,     22, (uint8_t *)dbs_parinit_storage1},
	{dbs_par_pk_storage2,						103,	  0x10,     0,     22, (uint8_t *)dbs_parinit_storage2},
	{dbs_par_pk_storage3,						125,	  0x10,     0,     22, (uint8_t *)dbs_parinit_storage3},
	{dbs_par_pk_storage4,						147,	  0x10,     0,     22, (uint8_t *)dbs_parinit_storage4},
	{dbs_par_pk_storage5,						169,	  0x10,     0,     22, (uint8_t *)dbs_parinit_storage5},	
	{dbs_par_pk_storage6,						191,	  0x10,     0,     22, (uint8_t *)dbs_parinit_storage6},
	{dbs_par_pk_storage7,						213,	  0x10,     0,     22, (uint8_t *)dbs_parinit_storage7},
	{dbs_par_pk_storage8,						235,	  0x10,     0,     22, (uint8_t *)dbs_parinit_storage8},
	{dbs_par_pk_storage9,						257,	  0x10,     0,     22, (uint8_t *)dbs_parinit_storage9},
	{dbs_par_pk_storage10,						279,	  0x10,     0,     22, (uint8_t *)dbs_parinit_storage10},
	{dbs_par_pk_seqnumfull,						301,	  0x10,     0,     1, (uint8_t *)dbs_parinit_seqnumfull}

};

/**
  * @brief Dbs_initParTable
  * @param
  * @retval
  * @note
  */
uint32_t Dbs_initDBS(uint32_t format)
{
    uint32_t result = 0;

    if (format == 1)
    {
        Dbs_setParDefault();
        printf("Database memory load defaults.\r\n");
    }

    result = Dbs_initParTable();
    if (result == 0)
    {
        printf("Database memory has errors,try to restore to default.\r\n");
        Dbs_setParDefault();
        printf("Database memory has errors,try to restore to default.\r\n");
        watchdog_reset();
    }
    else
    {
        return 1;
    }
}

/**
  * @brief Dbs_initParTable
  * @param
  * @retval
  * @note
  */
uint32_t Dbs_initParTable()
{
    uint32_t counter = 0;
    uint32_t n = 0;
    uint16_t data = 0;
    uint8_t temp0 = 0;
    uint8_t temp1 = 0;

    Epm_readData(dbs_par_amemstart + dbs_par_format[dbs_par_pk_isinit].offset, &temp0);
    Epm_readData(dbs_par_bmemstart + dbs_par_format[dbs_par_pk_isinit].offset, &temp1);

    if ((temp0 != 0X5A) && (temp1 != 0x5A))
    {
        for (counter = 0; counter < dbs_par_rows; counter++)
        {
            for (n = 0; n < dbs_par_format[counter].length; n++)
            {
                dbs_par_memory[dbs_par_format[counter].offset + n] = *(dbs_par_format[counter].pdata + n);
            }
        }
        dbs_par_memory[dbs_par_format[dbs_par_pk_isinit].offset] = 0X5A;
        data  = Crc_cal((uint8_t *)(dbs_par_memory + 2), dbs_par_memsize - 2);
        dbs_par_memory[0] = (uint8_t)(data & 0XFF);
        dbs_par_memory[1] = (uint8_t)((data >> 8) & 0XFF);
        for (counter = 0; counter < dbs_par_memsize; counter++)
        {
            Epm_wrtieData(dbs_par_amemstart + counter, dbs_par_memory[counter]);
            Epm_wrtieData(dbs_par_bmemstart + counter, dbs_par_memory[counter]);
        }
    }

    for (counter = 0; counter < dbs_par_memsize; counter++)
    {
        Epm_readData(dbs_par_amemstart + counter, (uint8_t *)(dbs_par_memory + counter));
    }

    data  = Crc_cal((uint8_t *)(dbs_par_memory + 2), dbs_par_memsize - 2);
    if (((uint8_t)(data & 0XFF) == dbs_par_memory[0]) && ((uint8_t)((data >> 8) & 0XFF) == dbs_par_memory[1]))
    {
        temp0 = 1;
    }
    else
    {
        temp0 = 0;
    }

    for (counter = 0; counter < dbs_par_memsize; counter++)
    {
        Epm_readData(dbs_par_bmemstart + counter, (uint8_t *)(dbs_par_memory + counter));
    }
    data  = Crc_cal((uint8_t *)(dbs_par_memory + 2), dbs_par_memsize - 2);

    if (((uint8_t)(data & 0XFF) == dbs_par_memory[0]) && ((uint8_t)((data >> 8) & 0XFF) == dbs_par_memory[1]))
    {
        temp1 = 1;
    }
    else
    {
        temp1 = 0;
    }

    if ((temp0 == 1) && (temp1 == 1))
    {
        return 1;
    }
    else if ((temp0 != 1) && (temp1 != 1))
    {
        return 0;
    }
    else if ((temp0 == 1) && (temp1 != 1))
    {
        for (counter = 0; counter < dbs_par_memsize; counter++)
        {
            Epm_readData(dbs_par_amemstart + counter, (uint8_t *)(dbs_par_memory + counter));
        }
        for (counter = 0; counter < dbs_par_memsize; counter++)
        {
            Epm_wrtieData(dbs_par_bmemstart + counter, dbs_par_memory[counter]);
        }
        return 1;
    }
    else if ((temp0 != 1) && (temp1 == 1))
    {
        for (counter = 0; counter < dbs_par_memsize; counter++)
        {
            Epm_readData(dbs_par_bmemstart + counter, (uint8_t *)(dbs_par_memory + counter));
        }
        for (counter = 0; counter < dbs_par_memsize; counter++)
        {
            Epm_wrtieData(dbs_par_amemstart + counter, dbs_par_memory[counter]);
        }
        return 1;
    }
}

/**
  * @brief Dbs_setParDefault
  * @param
  * @retval
  * @note
  */
uint32_t Dbs_setParDefault()
{
    Epm_wrtieData(dbs_par_amemstart + dbs_par_format[dbs_par_pk_isinit].offset, 0X00);
    Epm_wrtieData(dbs_par_bmemstart + dbs_par_format[dbs_par_pk_isinit].offset, 0X00);

    return Dbs_initParTable();
}

/**
  * @brief Dbs_setParValue
  * @param
  * @retval
  * @note
  */
uint32_t Dbs_setParValue(uint32_t pk, uint8_t *data, uint32_t length)
{
    uint32_t counter = 0;
    uint16_t temp = 0;

    if (pk >= dbs_par_rows)
    {
        return 0;
    }

    if (dbs_par_format[pk].lock == 1)
    {
        return 0;
    }

    if (dbs_par_format[pk].permission == 0x20)
    {
        return 0;
    }

    if (dbs_par_format[pk].length < length)
    {
        return 0;
    }

    /* 写入数据 */
    if (length == 0)
    {
        length = dbs_par_format[pk].length;
        for (counter = 0; counter < length; counter++)
        {
            dbs_par_memory[dbs_par_format[pk].offset + counter] = 0x00;
            Epm_wrtieData(dbs_par_amemstart + dbs_par_format[pk].offset + counter, 0x00);
            Epm_wrtieData(dbs_par_bmemstart + dbs_par_format[pk].offset + counter, 0x00);
        }
    }
    else
    {
        for (counter = 0; counter < length; counter++)
        {
            dbs_par_memory[dbs_par_format[pk].offset + counter] = *(data + counter);
            Epm_wrtieData(dbs_par_amemstart + dbs_par_format[pk].offset + counter, *(data + counter));
            Epm_wrtieData(dbs_par_bmemstart + dbs_par_format[pk].offset + counter, *(data + counter));
        }
        if (dbs_par_format[pk].length > length)
        {
            dbs_par_memory[dbs_par_format[pk].offset + length] = 0x00;
            Epm_wrtieData(dbs_par_amemstart + dbs_par_format[pk].offset + length, 0x00);
            Epm_wrtieData(dbs_par_bmemstart + dbs_par_format[pk].offset + length, 0x00);
        }
    }

    temp  = Crc_cal((uint8_t *)(dbs_par_memory + 2), dbs_par_memsize - 2);
    dbs_par_memory[0] = (uint8_t)(temp & 0XFF);
    dbs_par_memory[1] = (uint8_t)((temp >> 8) & 0XFF);

    Epm_wrtieData(dbs_par_amemstart + 0, (uint8_t)(temp & 0XFF));
    Epm_wrtieData(dbs_par_amemstart + 1, (uint8_t)((temp >> 8) & 0XFF));
    Epm_wrtieData(dbs_par_bmemstart + 0, (uint8_t)(temp & 0XFF));
    Epm_wrtieData(dbs_par_bmemstart + 1, (uint8_t)((temp >> 8) & 0XFF));

    return 1;
}


/**
  * @brief Dbs_getParValue
  * @param
  * @retval
  * @note
  */
uint32_t Dbs_getParValue(uint32_t pk, uint8_t *data, uint32_t *length)
{
    uint32_t counter = 0;

    if (pk >= dbs_par_rows)
    {
        return 0;
    }

    if (dbs_par_format[pk].lock == 1)
    {
        return 0;
    }

    if (dbs_par_format[pk].permission == 0x30)
    {
        return 0;
    }

    *length = dbs_par_format[pk].length;
    for (counter = 0; counter < dbs_par_format[pk].length; counter++)
    {
        *(data + counter) = dbs_par_memory[dbs_par_format[pk].offset + counter];
    }

    return 1;
}

/**
  * @brief Dbs_getParLength
  * @param
  * @retval
  * @note
  */
uint32_t Dbs_getParLength(uint32_t pk, uint32_t *length)
{
    if (pk >= dbs_par_rows)
    {
        return 0;
    }

    *length = dbs_par_format[pk].length;
    return 1;
}








